package com.example.g7640.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.g7640.builder.ResultBuilder;
import com.example.g7640.dto.*;
import com.example.g7640.entity.Administrator;
import com.example.g7640.entity.Customer;
import com.example.g7640.enums.TrueFalseEnum;
import com.example.g7640.enums.UserType;
import com.example.g7640.exception.BizException;
import com.example.g7640.mapper.AdministratorMapper;
import com.example.g7640.service.AdministratorService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.g7640.service.UserService;
import com.example.g7640.util.CollectionUtil;
import com.example.g7640.util.PasswordUtil;
import com.example.g7640.util.RoleCheckUtil;
import com.example.g7640.util.SessionLocal;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author
 * @since 2024-03-18
 */
@Service
public class AdministratorServiceImpl extends ServiceImpl<AdministratorMapper, Administrator> implements AdministratorService, UserService {

    @Resource
    AdministratorMapper administratorMapper;

    @Override
    public Boolean add(Administrator administrator) {
        Administrator a = new Administrator();
        a.setPassword(PasswordUtil.encodePassword(administrator.getPassword()));
        a.setAccount(administrator.getAccount());
        a.setName(administrator.getName());
        a.setCreatedAt(LocalDateTime.now());

        LambdaQueryWrapper<Administrator> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Administrator::getAccount, administrator.getAccount());
        List<Administrator> list = administratorMapper.selectList(wrapper);
        if (!list.isEmpty()) {
            throw new BizException("account is repeated");
        }
        administratorMapper.insert(a);
        return true;
    }

    @Override
    public Boolean setPassword(Administrator administrator) {
        Administrator a = new Administrator();
        a.setId(administrator.getId());
        a.setPassword(PasswordUtil.encodePassword(administrator.getPassword()));
        this.updateById(a);
        return true;
    }

    @Override
    public Boolean setName(Administrator administrator) {
        Administrator a = new Administrator();
        a.setId(administrator.getId());
        a.setName(administrator.getName());
        this.updateById(a);
        return true;
    }

    @Override
    public List<AdminDto> getList() {
        return this.list().stream()
                .map(a -> new AdminDto(a.getId(), a.getName(), a.getAccount()))
                .collect(Collectors.toList());
    }

    @Override
    public Administrator getInfo(Administrator administrator) {
        Administrator a = this.getById(administrator);
        a.setPassword(null);
        return a;
    }

    @Override
    public SessionDto login(LoginDto loginDto) {
        Administrator adminDb = this.queryByAccount(loginDto.getAccount());
        if(adminDb == null){
            throw new BizException("admin account is not existed");
        }
        String dbPassword = adminDb.getPassword();
        if(!dbPassword.equals(loginDto.getPassword())){
            throw new BizException("password is wrong");
        }

        SessionDto sessionDto = new SessionDto();
        sessionDto.setId(adminDb.getId());
        sessionDto.setAccount(adminDb.getAccount());
        sessionDto.setName(adminDb.getName());
        sessionDto.setType(UserType.admin.getIndex());
        return sessionDto;
    }

    @Override
    public void register(RegistDto registDto) {
        throw new BizException("Admin can not register");
    }

    @Override
    public Integer getType() {
        return UserType.admin.getIndex();
    }

    @Override
    public void changePassword(UserChangePasswordDto u) {
        System.out.println("sessionType" + SessionLocal.getSession().getType());
        RoleCheckUtil.checkAdmin();
        Integer id = SessionLocal.getLoginId();
        Administrator administrator = administratorMapper.selectById(id);
        if(administrator == null){
            throw new BizException("admin is not exist");
        }
        String oldPassword = PasswordUtil.encodePassword(u.getOldPass());
        String newPassword = PasswordUtil.encodePassword(u.getNewPass());
        if(!Objects.equals(oldPassword,administrator.getPassword())){
            throw new BizException("Old password wrong");
        }
        administrator.setPassword(newPassword);
        administrator.setUpdatedAt(LocalDateTime.now());
        administratorMapper.updateById(administrator);
    }


    private Administrator queryByAccount(String account){
        LambdaQueryWrapper<Administrator> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Administrator::getAccount,account);
        List<Administrator> administrators = administratorMapper.selectList(wrapper);
        return CollectionUtil.getFirstObj(administrators);
    }
}
